<?php

class BidDao extends CFormModel
{

    const BID_TYPE_CASH = 'cash';

    const BID_TYPE_PROMO = 'promo';

    public $customerId;

    public function bidTypeMapper()
    {
        return array(
            self::BID_TYPE_CASH => '',
            self::BID_TYPE_PROMO => ''
        );
    }

    public function type($type)
    {
        $typeMapper = $this->bidTypeMapper();
        if (array_key_exists($type, $typeMapper)) {
            $bidTypeClass = Yii::import($typeMapper[$type]);
            $bidTypeObj = new $bidTypeClass();
            return $bidTypeObj;
        }
        return false;
    }

    public $customerId;

    public $timeOutLeft = 1;

    public $retry;

    protected $_bidActions = array();

    protected $_bidRetryList = array();

    protected $redis = null;

    public function init()
    {
        parent::init();
        $this->redis = Yii::app()->dbRedis;
    }

    public function setCustomerId($customerId)
    {
        $this->customerId = $customerId;
        return $this;
    }

    public function addBidActionModel($bidModel)
    {
        $this->_bidActions[] = $bidModel;
        return $this;
    }

    public function addBidAction($bidType, $amount, $sourceType, $note = null)
    {
        $bidType = $this->createBidType($bidType);
        $bidType->customer_id = $this->customerId;
        $bidType->attributes = array(
            'amount' => $amount,
            'bid_source_type' => $sourceType,
            'note' => $note
        );
        
        $this->addBidActionModel($bidType);
        return $this;
    }

    public function createBidType($bidType)
    {
        $bidTypeObj = null;
        if (is_string($bidType)) {
            $bidTypeClass = Yii::import($bidType);
            $bidTypeObj = new $bidTypeClass();
        } else {
            $bidTypeObj = $bidType;
        }
        return $bidTypeObj;
    }

    public function bidActions()
    {
        return $this->_bidActions;
    }

    public function run()
    {
        $timeOut = time() + $this->timeOutLeft;
        do {
            $this->retry = time() < $timeOut;
            
            if ($this->lock()) {
                usleep(self::LOOP_INTERVAL);
                continue;
            }
            /*
             * $transaction = Yii::app()->db->getCurrentTransaction();
             * if (empty($transaction)) {
             * $transaction = Yii::app()->db->beginTransaction();
             * }
             */
            try {
                foreach ($this->bidActions() as $bidAction) {
                    if ($bidAction->validate()) {
                        $bidAction->save();
                    } else {
                        $this->addError('bidRun', $bidAction->getErrors());
                    }
                }
                // $transaction->commit();
            } catch (Exception $e) {
                var_dump($e->getMessage());
                // $transaction->rollback();
            }
            
            return true;
        } while ($this->retry);
        
    }

    public function bidRetryList()
    {
        if (! empty($this->_bidRetryList)) {
            $this->_bidRetryList = new BidRetryList();
        }
        return $this->_bidRetryList;
    }

    public function timeOutProcess()
    {
        switch ($this->getScenario()) {
            case 'BID':
                return false;
                break;
            default:
                var_dump(1);
                // $this->bidRetryList()->addRetryList($this->_bidRetryList);
                break;
        }
    }

    public function lock()
    {
        return false;
        return ! $this->redis->setnx('lock', time());
    }

    public function getBids($bidType)
    {}

    public function unlock()
    {
        return $this->redis->delete('lock');
    }
}